package com.cyf.service;

import com.cyf.db.bean.*;
import com.cyf.db.mapper.*;
import com.cyf.pay.wxpay.service.WxpayService;
import com.cyf.service.bean.FeeFlowSmsNotice;
import com.cyf.util.DateUtil;
import com.cyf.util.SmsUtils;
import com.cyf.util.WeChatSubscriptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by cage on 2016/9/14.
 */
@Component
public class ScheduleTask {

    private static Map<String, List<FeeFlowSmsNotice>> needSmsNoticeMap = new ConcurrentHashMap<>();
    private static final long oneMinute = 60 * 1000;
    private static final long oneDay = 24 * 60 * oneMinute;
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private PayOrderMapper payOrderMapper;
    @Autowired
    private RegSmsMapper regSmsMapper;
    @Autowired
    private ParkingMapper parkingMapper;
    @Autowired
    private FeeFlowMapper feeFlowMapper;
    @Autowired
    private AppUserCarMapper appUserCarMapper;
    @Autowired
    private InviteRecordMapper inviteRecordMapper;
    @Autowired
    private VisitorRecordMapper visitorRecordMapper;

    @Autowired
    private LocalAdminparaMapper localAdminparaMapper;

    @Autowired
    private WxpayService wxpayService;
    @Autowired
    private WeChatSubscriptionUtil weChatSubscriptionUtil;

    //每1分钟删除一下超时注册短信
    @Scheduled(cron = "0 */1 * * * *")
    public void SmsTimeout() throws InterruptedException {
        Date now = new Date();
        now.setTime(now.getTime() - 20 * oneMinute);
        regSmsMapper.deleteTimeout(now);
    }

    // 每天凌晨更新所有人的sendMsg状态为0。代表今天没有发送过月卡过期消息
    @Scheduled(cron = "0 0 0 */1 * *")
    public void updateUserMsgStatus() {
        try {
            appUserCarMapper.updateSendMsg();
            logger.info("更新sendMsg状态成功！！！");
        } catch (Exception e) {
            logger.error("更新sendMsg状态异常：", e);
        }
    }

    // 更新 未知支付状态 的账单
    @Scheduled(cron = "0 */10 * * * *")
    public void treatPayOrder() {
        List<PayOrder> payOrders;
        try {
            payOrders = payOrderService.getUntreatedPayOrder();
        } catch (Exception e) {
            logger.error("处理支付状态未知的订单异常：{}", e);
            return;
        }
        if (null != payOrders && payOrders.size() > 0) {
            for (PayOrder payOrder : payOrders) {
                payOrderService.updatePayOrderStatus(payOrder);
            }
        }
    }

    // 关闭 微信超时订单
    @Scheduled(cron = "30 */3 * * * *")
    public void closePayOrder() {
        Date date = DateUtil.getDateAfterSeconds(new Date(), -30 * 60);
        List<PayOrder> payOrders;
        try {
            payOrders = payOrderMapper.getNeedClosePayOrder(date);
        } catch (Exception e) {
            logger.error("处理支付状态未知的订单异常：{}", e);
            return;
        }
        if (null != payOrders && payOrders.size() > 0) {
            for (PayOrder payOrder : payOrders) {
                wxpayService.closeOrder(payOrder.getOrderNo());
            }
        }
    }

    // 删除30分钟前不知支付方式的订单  不删除订单
    //@Scheduled(cron = "0 */2 * * * *")
    //public void deleteUnknownPayWayOrder() {
        //Date now = new Date();
        //now.setTime(now.getTime() - 30 * oneMinute);
        //payOrderMapper.deleteUnknownPayWayOrder(now);
   // }

    // 每3分钟更新一次各个车场可用的地锁数量
    /*@Scheduled(cron = "10 *//*3 * * * *")
    public void updateEnableLockCount(){
        enableLockCountMap.update();
    }*/

    // 每天凌晨1点删除5天前的数据
    /*@Scheduled(cron = "0 0 1 * * *")
    public void deleteBookingTimeout(){
        Date now = new Date();
        now.setTime(now.getTime() - 10 * oneDay);
        bookingInfoMapper.deleteTimeout(now);
    }*/

    // 车位预约超时
   /* @Scheduled(cron = "0 *//*1 * * * *")
    public void timeout(){
        Date now = new Date();
        bookingService.timeout(now);
    }*/

    // 刷新一次订阅号的access_token
    @Scheduled(cron = "0 50 */1 * * *")
    public void getWeChatAccessToken() {
        weChatSubscriptionUtil.getWeChatAccessToken();
    }

    // 加载今天需要的短信通知（昨日收入详情）
    @Scheduled(cron = "0 0 1 * * *")
    public void getNeedSmsNotice() {
        needSmsNoticeMap.clear();

        List<Integer> parkingIds = localAdminparaMapper.getNeedSmsNoticeParkingIds();
        if (parkingIds != null && parkingIds.size() > 0) {
            for (Integer parkingId : parkingIds) {
                LocalAdminpara localAdminpara = localAdminparaMapper.getByParkingIdAndParaKey(parkingId, LocalAdminpara.SMS_NOTICE);
                if (localAdminpara.getParaValue() == null || localAdminpara.getParaValue().trim().length() == 0 || localAdminpara.getChuzu() == null || localAdminpara.getChuzu().trim().length() == 0) {
                    logger.warn("车场({})开启短信通知昨日收费情况功能，但信息不全！({})，({})", parkingId, localAdminpara.getParaValue(), localAdminpara.getChuzu());
                    continue;
                }
                LocalAdminpara projectNameAP = localAdminparaMapper.getByParkingIdAndParaKey(parkingId, LocalAdminpara.PROJECT_NAME);
                if (projectNameAP == null) {
                    logger.warn("车场({})的项目名称没有上传到云端！", parkingId);
                    continue;
                }
                putNeedSmsNoticeMap(localAdminpara.getParaValue().trim(), localAdminpara.getChuzu().trim(), parkingId, projectNameAP.getParaValue());
            }
        }

    }

    /**
     * 昨日收费情况，将发送短信的号码和时间 存储到map中
     *
     * @param mobileStrs  手机号
     * @param smsTime     发送时间
     * @param parkingId   车场id
     * @param parkingName 车场名称
     */
    private void putNeedSmsNoticeMap(String mobileStrs, String smsTime, int parkingId, String parkingName) {
        String[] mobiles = mobileStrs.split(",");
        ArrayList<FeeFlowSmsNotice> list = new ArrayList<>();
        List<FeeFlowSmsNotice> feeFlowSmsNotices = needSmsNoticeMap.get(smsTime);
        if (feeFlowSmsNotices != null) {
            list.addAll(feeFlowSmsNotices);
        }
        list.add(new FeeFlowSmsNotice(parkingId, Arrays.asList(mobiles), parkingName));
        needSmsNoticeMap.put(smsTime, list);
    }

    @Scheduled(cron = "0 */1 * * * *")
    public void feeFlowSmsNotice() {
        if (needSmsNoticeMap.size() > 0) {
            String curTime = DateUtil.formatDate(new Date(), "HH:mm");
            List<FeeFlowSmsNotice> feeFlowSmsNotices = needSmsNoticeMap.get(curTime);
            if (feeFlowSmsNotices != null) {
                for (FeeFlowSmsNotice feeFlowSmsNotice : feeFlowSmsNotices) {
                    FeeFlow feeFlow = feeFlowMapper.getByDayAndParkingId(Integer.parseInt(DateUtil.formatDate(DateUtil.getAfterDay(-1), "yyyyMMdd")),
                            feeFlowSmsNotice.getParkingId());
                    if (feeFlow != null) {
                        for (String mobile : feeFlowSmsNotice.getMobiles()) {
                            String txt = SmsUtils.getFeeFlowSmsTxt(feeFlow.getShouldfee(), feeFlow.getActualfee(),
                                    DateUtil.getAfterDay(-1), feeFlowSmsNotice.getParkingName());
                            try {
                                SmsUtils.SendSms(txt, mobile);
                            } catch (IOException e) {
                                logger.error("短信发送昨日收费情况异常：{}", e);
                            }
                        }
                    }
                }
                needSmsNoticeMap.remove(curTime);
            }
        }
    }

    // 检查邀请记录
    @Scheduled(cron = "0 */2 * * * *")
    public void checkInviteRecord() {
        inviteRecordMapper.timeout(new Date());
    }

    // 检查未处理的访客申请
    public void checkUnProcessVisitorRecord() {
        List<Integer> ids = visitorRecordMapper.timeout(new Date());
        if (ids == null) {
            return;
        }
        for (Integer id : ids) {
            visitorRecordMapper.updateStatusById(VisitorRecord.STATUS_EXPIRATION, id);
        }
    }
}
